feat: Enhance PyManager with app support and isolation features#1
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53b96595a9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| dest_resolved = dest_dir.resolve() | ||
| for name in names: | ||
| target = (dest_dir / name).resolve() | ||
| if not str(target).startswith(str(dest_resolved)): |
There was a problem hiding this comment.
Validate .7z members with path-aware containment
For .7z archives, this string-prefix check treats sibling paths as safe: with a destination like /data/tmp/extract_demo_123, a member named ../extract_demo_123_evil/x.py resolves outside the staging directory but still starts with the same string, after which py7zr.extractall() is invoked. Use Path.is_relative_to(dest_resolved) or os.path.commonpath so crafted archives cannot escape the extraction directory.
Useful? React with 👍 / 👎.
| if dest_root.exists(): | ||
| shutil.rmtree(dest_root, ignore_errors=True) |
There was a problem hiding this comment.
Stop running apps before replacing their files
When an archive is re-uploaded with the same app id while that app is running, this removes and replaces APPS_DIR/<id> without stopping the existing process. The later auto-run path will see the old process still registered and return Already running, so the updated app never starts and the old process keeps running against a deleted/replaced source tree.
Useful? React with 👍 / 👎.
| root = Path(script.get("root_dir") or "") | ||
| req_file = root / "requirements.txt" | ||
| if not req_file.exists(): | ||
| return "🟡 No requirements.txt found." |
There was a problem hiding this comment.
Install the requirements file that setup detected
Setup uses find_requirements_pkgs()/find_requirements_file() to detect nested files, so an archive shaped like subapp/main.py plus subapp/requirements.txt gets an Install & Run prompt. This installer only checks <root>/requirements.txt, reports no requirements found, and then runs the app with an empty venv for that supported layout.
Useful? React with 👍 / 👎.
| await present_setup_result(query.message.chat_id, context, script_id, result, f"🔄 Synced {script_id}.") | ||
| return | ||
|
|
||
| run_msg = await script_mgr.start_script(script_id) |
There was a problem hiding this comment.
Defer sync restarts until new dependencies are installed
On a Git sync where requirements.txt changed, this starts the newly pulled code before presenting the "Install new requirements & Restart" button. If the new commit imports a package that was just added to requirements, it launches with the stale venv and fails before the user can install it; defer the start until after reqinstall or install first when dependencies changed.
Useful? React with 👍 / 👎.
No description provided.